/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       water.frag
 * Author:     karooolek
 * Created on: Dec 18, 2009
 *
 **********************************************************************************************************************/

STRINGIZE(

varying vec4 position;
varying mat3 tbn;
varying mat3 modelMatrix;

uniform vec4 color;

uniform vec3 fresnel;

uniform samplerCube envMap;
uniform vec4 envColor;

uniform sampler2D normalMap;

uniform sampler2D foam;
uniform vec2 foamMinMax;

void main()
{
    // calculate normal
    vec3 n1 = 2.0 * vec3(texture2D(normalMap, vec2(gl_TexCoord[0]))) - 1.0;
    vec3 n2 = 2.0 * vec3(texture2D(normalMap, vec2(gl_TexCoord[1]))) - 1.0;
    vec3 N = normalize(tbn * (n1 + n2));
    
    // calculate view vector
    vec3 V = normalize(-vec3(position));
    
    // refracted color
    vec4 refr = color;
    
    // reflected color
    vec3 C = modelMatrix * reflect(-V, N);
    C.z = abs(C.z);
    vec4 refl = envColor;//textureCube(envMap, C);
    
    // fresnel effect
    float fresn = clamp(fresnel.x + fresnel.y * pow(1.0 - dot(N, V), fresnel.z), 0.0, 1.0);
    gl_FragColor = mix(refr, refl, fresn);
    
    // foam texture
    vec4 foam = texture2D(foam, gl_TexCoord[2].xy);
    float av = mix(foamMinMax.x, foamMinMax.y, 0.5);
    foam.a *= min(
                smoothstep(foamMinMax.x, av, gl_TexCoord[2].z),
                smoothstep(foamMinMax.y, av, gl_TexCoord[2].z)
                );
    
    gl_FragColor = vec4(mix(gl_FragColor.rgb, foam.rgb, foam.a), 1.0);
    
    // lighting for each light
    for(int i = 0; i != 4; ++i)
    {
        vec4 color = vec4(0.0);
        
        // calculate light vector and distance
        vec3 L = vec3(gl_LightSource[i].position - position);
        float d = length(L);
        L = normalize(L);
        
        // half vector
        vec3 H = normalize(L + V);
        
//        // calculate diffuse
//        color += color * gl_LightSource[i].diffuse * max(dot(N, L), 0.0);
        
        // calculate specular
        color += (1.0 - foam.a) * gl_LightSource[i].specular * pow(max(dot(N, H), 0.0), 40.0);
        
        // distance attenuation
        color *= 1.0 / (
            gl_LightSource[i].constantAttenuation +
            gl_LightSource[i].linearAttenuation * d +
            gl_LightSource[i].quadraticAttenuation * d * d
            );
        
        // spotlight attenuation
        float spotCos = dot(normalize(gl_LightSource[i].spotDirection), -L);
        color *=  smoothstep(gl_LightSource[i].spotCutoff - 1.0, gl_LightSource[i].spotExponent -1.0, spotCos);
        
//        // ambient light
//        color += color * gl_LightSource[i].ambient;
        
        // update fragment color
        gl_FragColor += color;
    }

    // clamp color
    gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
}

) // STRINGIZE
